import axios from 'axios';
axios.defaults.withCredentials = true;
const config = {
    "rpcURL": "/gateway/api/jsonrpc.jsp",
};

const RPCClient = function () {
    if (this.cookie) {
        try {
            this.cookie = JSON.parse(this.cookie);
        } catch (error) {
            // Do nothing
        }
    }
    this.acquireListeners = [];
};

RPCClient.ERROR_NEED_TOKEN = 592;

RPCClient.prototype.directRPC = function (method, parameters, callback) {
    axios({
        "url": config.rpcURL,
        "method": "POST",
        "data": {
            "jsonrpc": "2.0",
            "method": method,
            "params": parameters[0],
            "id": Date.now().toString() + "." + Math.round((Math.random() * 0xffff))
        },
        "responseType": "JSON",
        "contentType": "application/json;charset=UTF-8"
    }).then(function (result) {
        if (result.error) {
            let error = new Error(result.error.message);
            error.code = result.error.code;
            callback(error);
            return;
        }

        callback(null, result.data);

    }).catch(function (error) {
        callback(error);
    })

};

RPCClient.prototype.rpc = function (method, parameters, callback) {
    if (this.acquireListeners.length) {

        this.acquireListeners.push(function () {
            this.directRPC(method, parameters, callback);
        }.bind(this));

    } else {
        this.directRPC(method, parameters, (error, result) => {

            if (error) {
                callback(error);
            } else {
                callback(error, result);
            }

        });
    }

};


const rpcClient = new RPCClient();

var buildProxy = function (name, context) {

    return new Proxy(function () {
        var parameters = Array.prototype.slice.call(arguments, 0);
        return new Promise(function (resolve, reject) {
            rpcClient.rpc(context.join(".") + "." + name, parameters, function (error, result) {
                if (error) {
                    reject(error);
                } else {
                    resolve(result);
                }
            });
        })
    }, {
        "get": function (target, method) {
            if (!target[method]) {
                target[method] = buildProxy(method, context.concat([name]));
            }
            return target[method];
        }
    });
};

export default new Proxy({}, {

    get: function (target, domain) {
        if (!target[domain]) {
            target[domain] = new Proxy({}, {
                get: function (subTarget, method) {
                    if (["bind", "length", "name"].indexOf(method) < 0) {
                        if (!subTarget[method]) {
                            subTarget[method] = buildProxy(method, [domain]);
                        }
                        return subTarget[method];
                    } else {
                        return subTarget[method];
                    }
                }
            })
        }
        return target[domain];
    }
})